'''
Created on 20/03/2009

@author: eh01
'''
from xml.dom.minidom import parseString

class DST(object):
    '''
    A DST is never deleted, it is either associated with a DSO or not. 
    '''
    sort_order = None
    subject = None
    predicate = None
    object = None
    literal = None
    literal_type = None
    literal_language = None
    
    # This property isn't mapped to the database. It is just used to indicate not to return this DST when a DSO gets it's DSTs
    remove = False
    
    __opening_tag = "<"
    __closing_tag = "</"
    __end_tag = ">"
    __dst_tag_name = "dst"    
    __subject_tag_name = "subject"
    __predicate_tag_name = "predicate"
    __object_tag_name = "object"
    __literal_tag_name = "literal"
    __literal_type_tag_name = "literalType"
        
    def __init__(self, id=None, subject=None, predicate=None, object=None, literal=None, literal_type=None, xml_string=None):
        if xml_string is None:
            self.__id = id
            self.subject = subject
            self.predicate = predicate
            self.object = object
            self.literal = literal
            self.literal_type = literal_type
        else:
            xml = parseString(xml_string)
            self.subject = self.getValueForElement(self.__subject_tag_name, xml)
            self.predicate = self.getValueForElement(self.__predicate_tag_name, xml)
            self.object = self.getValueForElement(self.__object_tag_name, xml)
            self.literal = self.getValueForElement(self.__literal_tag_name, xml)
            self.literal_type = self.getValueForElement(self.__literal_type_tag_name, xml)

    def get_id(self):
        return self.__id
    
    def to_xml(self):               
        xml = self.__opening_tag + self.__dst_tag_name + self.__end_tag + \
                self.get_subject_xml() + \
                self.get_predicate_xml() + \
                self.get_object_xml() + \
                self.get_literal_xml() + \
                self.get_literal_type_xml() + \
                self.__closing_tag + self.__dst_tag_name + self.__end_tag
        return xml
        
    def get_subject_xml(self):
        xml = self.__opening_tag + self.__subject_tag_name + self.__end_tag + \
                self.subject + \
                self.__closing_tag + self.__subject_tag_name + self.__end_tag
        return xml 
    
    def get_predicate_xml(self):
        xml = self.__opening_tag + self.__predicate_tag_name + self.__end_tag + \
                self.predicate + \
                self.__closing_tag + self.__predicate_tag_name + self.__end_tag
        return xml
    
    def get_object_xml(self):
        xml = self.__opening_tag + self.__object_tag_name + self.__end_tag
        if self.object:
            xml += self.object
        xml += self.__closing_tag + self.__object_tag_name + self.__end_tag
        return xml

    def get_literal_xml(self):
        xml = self.__opening_tag + self.__literal_tag_name + self.__end_tag
        if self.literal:
            xml += str(self.literal)
        xml += self.__closing_tag + self.__literal_tag_name + self.__end_tag
        return xml

    def get_literal_type_xml(self):
        xml = self.__opening_tag + self.__literal_type_tag_name + self.__end_tag
        if self.literal_type:
            xml += self.literal_type
        xml += self.__closing_tag + self.__literal_type_tag_name + self.__end_tag
        return xml      
            
    def getValueForElement(self, element_name, xml):
        if xml.getElementsByTagName(element_name):
            # assume there will be only one element
            element = xml.getElementsByTagName(element_name)[0]

            if element.childNodes:
                # assume there is only one child node for that element
                child_node = element.childNodes[0]
                
                if child_node.nodeType == child_node.TEXT_NODE:
                    return child_node.data
                else:
                    return None
            else:
                return None
        else:
            return None
                
    id = property(get_id, None, None, None)
    
    def __cmp__(self, other):
        if self.id == other.id and \
            self.sort_order == other.sort_order and \
            self.subject == other.subject and \
            self.predicate == other.predicate and \
            self.object == other.object and \
            self.literal == other.literal and \
            self.literal_type == other.literal_type and \
            self.literal_language == other.literal_language and \
            self.remove == other.remove:
            return 0
        else:
            return -1